
#import "UITableView+JKIndexView.h"
#import <objc/runtime.h>
#import "JKIndexView.h"

@interface SCWeakProxy : NSObject
@property (nonatomic, weak) id target;
@end
@implementation SCWeakProxy
@end

@interface UITableView () <JKIndexViewDelegate>

@property (nonatomic, strong) JKIndexView *jk_indexView;

@end

@implementation UITableView (JKIndexView)

#pragma mark - Swizzle Method

+ (void)load
{
    [self swizzledSelector:@selector(JKIndexView_layoutSubviews) originalSelector:@selector(layoutSubviews)];
}

+ (void)swizzledSelector:(SEL)swizzledSelector originalSelector:(SEL)originalSelector
{
    Class class = [self class];
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    BOOL didAddMethod =
    class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

- (void)JKIndexView_layoutSubviews {
    [self JKIndexView_layoutSubviews];
    
    if (!self.jk_indexView) {
        return;
    }
    if (self.superview && !self.jk_indexView.superview) {
        [self.superview addSubview:self.jk_indexView];
    }
    else if (!self.superview && self.jk_indexView.superview) {
        [self.jk_indexView removeFromSuperview];
    }
    if (!CGRectEqualToRect(self.jk_indexView.frame, self.frame)) {
        self.jk_indexView.frame = self.frame;
    }
    [self.jk_indexView refreshCurrentSection];
}

#pragma mark - JKIndexViewDelegate

- (void)indexView:(JKIndexView *)indexView didSelectAtSection:(NSUInteger)section
{
    if (self.jk_indexViewDelegate && [self.delegate respondsToSelector:@selector(tableView:didSelectIndexViewAtSection:)]) {
        [self.jk_indexViewDelegate tableView:self didSelectIndexViewAtSection:section];
    }
}

- (NSUInteger)sectionOfIndexView:(JKIndexView *)indexView tableViewDidScroll:(UITableView *)tableView
{
    if (self.jk_indexViewDelegate && [self.delegate respondsToSelector:@selector(sectionOfTableViewDidScroll:)]) {
        return [self.jk_indexViewDelegate sectionOfTableViewDidScroll:self];
    } else {
        return JKIndexViewInvalidSection;
    }
}

#pragma mark - Public Methods

- (void)jk_refreshCurrentSectionOfIndexView {
    [self.jk_indexView refreshCurrentSection];
}

// 索引条显示隐藏
- (void)setJk_indexViewHidden:(BOOL)jk_indexViewHidden {
	self.jk_indexView.hidden = jk_indexViewHidden;
}

#pragma mark - Private Methods

- (JKIndexView *)createIndexView {
    JKIndexView *indexView = [[JKIndexView alloc] initWithTableView:self configuration:self.jk_indexViewConfiguration];
    indexView.translucentForTableViewInNavigationBar = self.jk_translucentForTableViewInNavigationBar;
    indexView.startSection = self.jk_startSection;
    indexView.delegate = self;
    return indexView;
}

#pragma mark - Getter and Setter

- (JKIndexView *)jk_indexView
{
    return objc_getAssociatedObject(self, @selector(jk_indexView));
}

- (void)setJk_indexView:(JKIndexView *)jk_indexView
{
    if (self.jk_indexView == jk_indexView) return;
    
    objc_setAssociatedObject(self, @selector(jk_indexView), jk_indexView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (JKIndexViewConfiguration *)jk_indexViewConfiguration
{
    JKIndexViewConfiguration *jk_indexViewConfiguration = objc_getAssociatedObject(self, @selector(jk_indexViewConfiguration));
    if (!jk_indexViewConfiguration) {
        jk_indexViewConfiguration = [JKIndexViewConfiguration configuration];
    }
    return jk_indexViewConfiguration;
}

- (void)setJk_indexViewConfiguration:(JKIndexViewConfiguration *)jk_indexViewConfiguration
{
    if (self.jk_indexViewConfiguration == jk_indexViewConfiguration) return;
    
    objc_setAssociatedObject(self, @selector(jk_indexViewConfiguration), jk_indexViewConfiguration, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (id<SCTableViewSectionIndexDelegate>)jk_indexViewDelegate
{
    SCWeakProxy *weakProxy = objc_getAssociatedObject(self, @selector(jk_indexViewDelegate));
    return weakProxy.target;
}

- (void)setJk_indexViewDelegate:(id<SCTableViewSectionIndexDelegate>)jk_indexViewDelegate
{
    if (self.jk_indexViewDelegate == jk_indexViewDelegate) return;
    
    SCWeakProxy *weakProxy = [SCWeakProxy new];
    weakProxy.target = jk_indexViewDelegate;
    objc_setAssociatedObject(self, @selector(jk_indexViewDelegate), weakProxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)jk_translucentForTableViewInNavigationBar
{
    NSNumber *number = objc_getAssociatedObject(self, @selector(jk_translucentForTableViewInNavigationBar));
    return number.boolValue;
}

- (void)setJk_translucentForTableViewInNavigationBar:(BOOL)jk_translucentForTableViewInNavigationBar
{
    if (self.jk_translucentForTableViewInNavigationBar == jk_translucentForTableViewInNavigationBar) return;
    
    objc_setAssociatedObject(self, @selector(jk_translucentForTableViewInNavigationBar), @(jk_translucentForTableViewInNavigationBar), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    self.jk_indexView.translucentForTableViewInNavigationBar = jk_translucentForTableViewInNavigationBar;
}

- (NSArray<NSString *> *)jk_indexViewDataSource
{
    return objc_getAssociatedObject(self, @selector(jk_indexViewDataSource));
}

- (void)setJk_indexViewDataSource:(NSArray<NSString *> *)jk_indexViewDataSource
{
    if (self.jk_indexViewDataSource == jk_indexViewDataSource) return;
    objc_setAssociatedObject(self, @selector(jk_indexViewDataSource), jk_indexViewDataSource.copy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    if (jk_indexViewDataSource.count > 0) {
        if (!self.jk_indexView) {
            self.jk_indexView = [self createIndexView];
            [self.superview addSubview:self.jk_indexView];
        }
        self.jk_indexView.dataSource = jk_indexViewDataSource.copy;
        self.jk_indexView.hidden = NO;
    }
    else {
        self.jk_indexView.hidden = YES;
    }
}

- (NSUInteger)jk_startSection {
    NSNumber *number = objc_getAssociatedObject(self, @selector(jk_startSection));
    return number.unsignedIntegerValue;
}

- (void)setJk_startSection:(NSUInteger)jk_startSection {
    if (self.jk_startSection == jk_startSection) return;
    
    objc_setAssociatedObject(self, @selector(jk_startSection), @(jk_startSection), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    self.jk_indexView.startSection = jk_startSection;
}

@end
